#ifndef __SYMMALG_H__
#define __SYMMALG_H__

#include <QString>
#include "CString.h"
extern "C" {
#include "openssl/err.h"
#include "openssl/evp.h"
#include "openssl/ec.h"
#include <openssl/pem.h>
}

typedef enum {
    TDES,
    DES,
    SM4,
    AES128
}ALG_TYPE;


typedef enum {
    ECB,
    CBC
}ALG_MODE;

typedef enum {
    TDES_IV_LEN         = 0x08,
    TDES_KEY_LEN        = 0x10,
    DES3_ALL_KEY_LEN    = 0x18,
    DES3_ONE_KEY_LEN    = 0x08,
    DES_IV_LEN          = 0x08,
    DES_KEY_LEN         = 0x08,
    SM4_IV_LEN          = 0x10,
    SM4_KEY_LEN         = 0x10,
    AES128_IV_LEN       = 0x10,
    AES128_KEY_LEN      = 0x10,
    TDES_BLACK_LEN      = 0x08,
    DES_BLACK_LEN       = 0x08,
    SM4_BLACK_LEN       = 0x10,
    AES128_BLACK_LEN    = 0x10,
}ALG_BLACK_LEN;

typedef enum {
    ALG_MAX_LEN         = 2048,
    ALG_KEY_MAX_LEN     = 36,
    ALG_IV_MAX_LEN      = 36,
    ALG_BLACK_MAC_LEN   = 16
}ALG_NUM;

class SYMMALG
{
public:
    SYMMALG();
    ~SYMMALG();

    uint32_t alg_black(ALG_TYPE type);

    CString alg_encrypt(const CString& data, const CString& key, const CString& iv, const ALG_TYPE type, const ALG_MODE mode = ECB);

    CString alg_decrypt(const CString& data, const CString& key, const CString& iv, const ALG_TYPE type, const ALG_MODE mode = ECB);

    bool alg_encrypt(unsigned char* data, int data_len, unsigned char* key, unsigned char* iv, unsigned char* out, int &out_len,
                     const ALG_TYPE type, const ALG_MODE mode = ECB);

    bool alg_decrypt(unsigned char* data, int data_len, unsigned char* key, unsigned char* iv, unsigned char* out, int &out_len,
                     const ALG_TYPE type, const ALG_MODE mode = ECB);

    CString alg_mac(const CString& data, const CString& key, const CString& iv, ALG_TYPE type);
    void MAC(QString* out, QString in, uint16_t inlen, uint8_t* key, uint8_t* iv, uint32_t alg_mode);

private:
    EVP_CIPHER_CTX* ctx = NULL;
};

#endif // !__SYMMALG_H__




